package com.miku.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miku.blog.domain.Photo;
import com.miku.blog.domain.PhotoAlbum;
import com.miku.blog.domain.dto.PhotoAddDTO;
import com.miku.blog.domain.dto.PhotoDTO;
import com.miku.blog.domain.param.ReceptionParam;
import com.miku.blog.domain.pojo.LoginUser;
import com.miku.blog.domain.pojo.ResponseResult;
import com.miku.blog.domain.pojo.SystemConstance;
import com.miku.blog.domain.vo.PageVo;
import com.miku.blog.domain.vo.PhotoVo;
import com.miku.blog.eume.HttpStatusEnum;
import com.miku.blog.exception.SystemException;
import com.miku.blog.service.PhotoAlbumService;
import com.miku.blog.service.PhotoService;
import com.miku.blog.mapper.PhotoMapper;
import com.miku.blog.utils.BeanCopyUtils;
import com.miku.blog.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author Miku
* @description 针对表【tb_photo(照片)】的数据库操作Service实现
* @createDate 2022-06-09 01:30:28
*/
@Service
public class PhotoServiceImpl extends ServiceImpl<PhotoMapper, Photo>
    implements PhotoService{

    @Lazy
    @Autowired
    private PhotoAlbumService photoAlbumService;

    @Override
    public ResponseResult getPhotos(Integer current, Integer size,Integer albumsId) {

        PhotoAlbum photoAlbum = photoAlbumService.getById(albumsId);
        if ((SystemConstance.STATUS_PRIVATE.equals(photoAlbum.getStatus()) && !checkAdmin())){
            return ResponseResult.ok();
        }


        Page<Photo> page = new Page<>(current, size);
        LambdaQueryWrapper<Photo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Photo::getAlbumId,albumsId)
                .eq(Photo::getIsDelete,SystemConstance.NOT_DELETE);
        page(page,queryWrapper);
        List<Photo> photos = page.getRecords();
        List<String> srcList = photos.stream()
                .map(Photo::getPhotoSrc)
                .collect(Collectors.toList());

        PhotoAlbum album = photoAlbumService.getById(albumsId);

        PhotoVo photoVo = new PhotoVo();
        photoVo.setPhotoList(srcList)
                .setAlbumCover(album.getAlbumCover())
                .setAlbumName(album.getAlbumName());

        return ResponseResult.ok().setData(photoVo);
    }


    @Override
    public ResponseResult getPhotoList(Integer current, Integer size, @Nullable Integer albumId, Integer isDelete) {
        Page<Photo> page = new Page<>(current, size);
        LambdaQueryWrapper<Photo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(albumId),Photo::getAlbumId,albumId)
                .eq(Photo::getIsDelete, isDelete);
        page(page,queryWrapper);
        List<PhotoDTO> photoDTOS = BeanCopyUtils.copyListByType(page.getRecords(), PhotoDTO.class);
        PageVo<PhotoDTO> pageVo = new PageVo<>(page.getTotal(),photoDTOS);
        return ResponseResult.ok().setData(pageVo);
    }


    @Transactional
    @Override
    public ResponseResult addPhotos(PhotoAddDTO photoAddDTO) {
        Integer albumId = photoAddDTO.getAlbumId();
        List<String> photoUrlList = photoAddDTO.getPhotoUrlList();
        if (Objects.isNull(albumId) || Objects.isNull(photoUrlList) || photoUrlList.size() <= 0){
            return new ResponseResult(HttpStatusEnum.PARAM_ERROR);
        }
        photoUrlList.stream()
                .peek(url -> {
                    Photo photo = new Photo();
                    photo.setPhotoSrc(url)
                            .setAlbumId(albumId);
                    if (!save(photo)) {
                        throw new SystemException(HttpStatusEnum.INSERT_DATA_ERROR);
                    }
                }).collect(Collectors.toList());
        return ResponseResult.ok();
    }


    @Transactional
    @Override
    public ResponseResult delPhotoByLogic(ReceptionParam receptionParam) {
        List<Integer> idList = receptionParam.getIdList();
        Integer isDelete = receptionParam.getIsDelete();
        if (Objects.isNull(isDelete) || Objects.isNull(idList) || idList.size() <= 0){
            return new ResponseResult(HttpStatusEnum.PARAM_ERROR);
        }
        LambdaUpdateWrapper<Photo> updateWrapper = new LambdaUpdateWrapper<>();
        for (Integer id : idList) {
            updateWrapper.clear();
            updateWrapper.eq(Photo::getId,id)
                    .set(Photo::getIsDelete,isDelete);
            if (!update(updateWrapper)){
                throw new SystemException(HttpStatusEnum.UPDATE_DATA_ERROR);
            }
        }
        return ResponseResult.ok();
    }


    @Override
    public ResponseResult delPhotos(Integer[] idList) {
        if (!removeBatchByIds(Arrays.asList(idList))){
            return new ResponseResult(HttpStatusEnum.REMOVE_DATA_ERROR);
        }
        return ResponseResult.ok();
    }

    @Override
    public ResponseResult updatePhoto(Photo photo) {
        Integer id = photo.getId();
        String photoSrc = photo.getPhotoSrc();
        if (Objects.isNull(id) || !StringUtils.hasText(photoSrc)){
            return new ResponseResult(HttpStatusEnum.PARAM_ERROR);
        }
        String photoDesc = photo.getPhotoDesc();
        String photoName = photo.getPhotoName();
        LambdaUpdateWrapper<Photo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Photo::getId,id)
                .set(Photo::getPhotoSrc,photoSrc)
                .set(StringUtils.hasText(photoDesc),Photo::getPhotoDesc,photoDesc)
                .set(StringUtils.hasText(photoName),Photo::getPhotoName,photoName);
        if (!update(updateWrapper)){
            return new ResponseResult(HttpStatusEnum.UPDATE_DATA_ERROR);
        }
        return ResponseResult.ok();
    }

    @Override
    public boolean updatePhotoById(Integer albumId, Integer photoId){
        LambdaUpdateWrapper<Photo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Photo::getId,photoId)
                .set(Photo::getAlbumId,albumId);
        return update(updateWrapper);
    }



    @Override
    public long getPhotoCountByAlbumId(Integer albumId){
        LambdaQueryWrapper<Photo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Photo::getAlbumId,albumId)
                .eq(Photo::getIsDelete,SystemConstance.NOT_DELETE);
        return count(queryWrapper);
    }


    @Override
    public boolean delPhotoByAlbumId(Integer albumId){

        LambdaUpdateWrapper<Photo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Photo::getAlbumId,albumId);

        return remove(updateWrapper);
    }



    private boolean checkAdmin(){

        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (SystemConstance.ROLE_ADMIN_ID.equals(loginUser.getRole().getId())){
                return true;
            }
        } catch (Exception exception) {
            return false;
        }
        return false;
    }
}




